package com.lanyou.esb.web.serviceTesting;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.domain.ParamSetting;
import com.lanyou.cook.paramsetting.ParamSettingReppository;
import com.lanyou.cook.repository.FieldSystemRepository;
import com.lanyou.cook.repository.SystemInterfaceRepository;
import com.lanyou.cook.service.UserLogService;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.cook.util.gson.GsonUtil;
import com.lanyou.esb.common.CommonUtils;
import com.lanyou.esb.datadictionary.AuditStatusType;
import com.lanyou.esb.datadictionary.EnableType;
import com.lanyou.esb.datadictionary.IfOperationType;
import com.lanyou.esb.datadictionary.IfReqType;
import com.lanyou.esb.entity.Http;
import com.lanyou.esb.repository.HttpRepository;
import com.lanyou.esb.service.HttpService;
import com.lanyou.esb.service.ServiceTestingService;
import com.lanyou.esb.service.ServiceUsabilityService;
import com.lanyou.esb.service.TokenService;
import com.lanyou.esb.vo.HttpVo;
import com.lanyou.esb.vo.TokenVo;
import com.lanyou.esb.web.param.ServiceTestingParam;

/**
 * 服务调用方测试
 * 
 * @author Davey.wu
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/serviceConsumerTesting")
public class ServiceConsumerTestingController {
	// TODO TEST
	@Autowired
	private ServiceUsabilityService serviceUsabilityService;
	@Autowired
	private HttpService httpInterfaceService;
	@Autowired
	private ServiceTestingService serviceTestingService;
	@Autowired
	private TokenService interfaceTokenService;
	@Autowired
	private UserSessionService userSessionService;
	@PersistenceContext
	private EntityManager entityManager;
	@Autowired
	private SystemInterfaceRepository systemInterfaceRepository;

	@Autowired
	private FieldSystemRepository fieldSystemRepository;
	@Autowired
	private UserLogService userLogService;

	@Autowired
	private HttpRepository httpRepository;

	@Autowired
	private ParamSettingReppository paramSettingReppository;

	/**
	 * 获取HTTP接口测试信息
	 * 
	 * @param interfaceId
	 *            ：接口标识
	 * @param type
	 * @return
	 */
	@RequestMapping(value = "/getHttpInterfaceInfos", produces = "application/json")
	public String getHttpInterfaceInfos(String interfaceId) {
		Http http = httpInterfaceService.getHttp(interfaceId,
				AuditStatusType.AUDITED.ValueCode, EnableType.ENABLE.ValueCode);
		if (http == null) {
			return GsonUtil.getDefaultGson().toJson(new HttpVo());
		}
		String pubUrl = http.getPubUrl();
		// 获取测试地址配置参数
		ParamSetting paramSetting = paramSettingReppository
				.findByParamName(Constants.SERVERADDRESS);

		// 更改发布地址为测试地址
		if (paramSetting != null
				&& pubUrl.indexOf(paramSetting.getParamValue() + "/") >= 0) {
			pubUrl = pubUrl.replaceFirst(paramSetting.getParamValue() + "/",
					paramSetting.getParamValue() + "/"
							+ CommonUtils.SERVICE_TEST_SUFFER + "/");
		}

		HttpVo httpVo = new HttpVo();
		String requestMess = http.getRequestMess();
		Map<String, Object> authInfo = new HashMap<>(3);
		authInfo.put(CommonUtils.APPLY_KEY, "");
		authInfo.put(CommonUtils.ACCESS_TOKEN, "");
		authInfo.put(CommonUtils.CALL_SYSTEM_CODE, "");
		// 格式化请求信息，并添加核验信息
		requestMess = serviceTestingService.formateRequestMess(
				http.getAuthType(), authInfo, requestMess);
		httpVo.setId(http.getId());
		httpVo.setCode(http.getCode());
		httpVo.setName(http.getName());
		httpVo.setPubUrl(pubUrl);
		httpVo.setType(http.getType());
		httpVo.setAuthType(http.getAuthType());
		httpVo.setRequest(http.getRequest());
		httpVo.setDataFormate(http.getDataFormate());
		httpVo.setRequestMess(requestMess);
		httpVo.setContentType(http.getContentType());
		httpVo.setSystemCode(http.getSystemCode());
		httpVo.setVersion(http.getVersion());
		httpVo.setOperationType(http.getOperationType());
		httpVo.setSoapActionUri(http.getSoapActionUri());

		return GsonUtil.getDefaultGson().toJson(httpVo);
	}

	/**
	 * 获取令牌信息
	 * 
	 * @param interfaceId
	 *            ：接口标识
	 * @return
	 */
	@RequestMapping(value = "/getTokenInfos", produces = "application/json")
	public String getTokenInfos(String interfaceId) {
		List<TokenVo> tokenList = interfaceTokenService.findToken(interfaceId,
				UserSessionService.getCurrentAuthenticatedUserCode());
		String tokenJson = "";
		if (tokenList != null) {
			JsonArray jsonDatas = new JsonArray();
			for (TokenVo vo : tokenList) {
				JsonObject jo = new JsonObject();
				jo.addProperty(CommonUtils.MSG_FIELD_ID, vo.getAppKey() + ","
						+ vo.getCallSytemCode());
				jo.addProperty(CommonUtils.MSG_FIELD_NAME,
						vo.getCallSystemName());
				jsonDatas.add(jo);
			}
			JsonObject jsonResult = new JsonObject();
			jsonResult.add(CommonUtils.MSG_FIELD_CONTENT, jsonDatas);
			tokenJson = jsonResult.toString();
		}
		if (StringUtils.isBlank(tokenJson)) {
			return "{\"" + CommonUtils.MSG_FIELD_CONTENT + "\":[]}";
		}
		return tokenJson;
	}

	/**
	 * 服务测试请求发送
	 * 
	 * @param param
	 *            :查询参数
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	@RequestMapping(value = "/serviceTesting", produces = "application/json", method = RequestMethod.POST)
	public String serviceTesting(@RequestBody ServiceTestingParam param)
			throws HttpException, IOException, URISyntaxException {
		// 只能测试查找类型的接口
		if (StringUtils.isBlank(param.getOperationType())
				|| !IfOperationType.QUERY.ValueCode.equals(param
						.getOperationType())) {
			Map<String, Object> result = new HashMap<String, Object>();
			result.put(CommonUtils.MSG_FIELD_RESULT, "只能测试查找类型的接口");
			return GsonUtil.getDefaultGson().toJson(result);
		}
		// TODO test
		// serviceUsabilityService.serviceUsabilityTest();
		if (StringUtils.isBlank(param.getRequest())) {
			param.setRequest(IfReqType.GET.ValueCode);
		}
		Map<String, Object> result = serviceTestingService.sendRequest(param,
				true);
		if (result == null) {
			return "{}";
		}
		String json = GsonUtil.getDefaultGson().toJson(result);
		return json;
	}

	/**
	 * 申请访问令牌
	 * 
	 * @param applyKey
	 *            :密钥
	 * @param systemCode
	 *            ：系统编码
	 * @param interfaceCode
	 *            ：接口编码
	 * @param version
	 *            ：接口版本
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	@RequestMapping(value = "/aquiredToken", produces = "application/json")
	public String aquiredToken(String applyKey, String systemCode,
			String interfaceCode, String version) throws HttpException,
			IOException, URISyntaxException {
		// 获取测试地址配置参数
		ParamSetting paramSetting = paramSettingReppository
				.findByParamName(Constants.SERVERADDRESS);
		if (paramSetting == null
				|| StringUtils.isBlank(paramSetting.getParamValue())) {
			Map<String, String> result = new HashMap<>();
			result.put(CommonUtils.MSG_FIELD_ERR_MSG, "服务发布地址参数配置有误！");
			return GsonUtil.getDefaultGson().toJson(result);
		}
		return httpInterfaceService.aquiredToken(paramSetting.getParamValue(),
				applyKey, systemCode, interfaceCode, version);
	}

}
